/**
 * 映射(Map)模块使用示例 (zh-map.js)
 * 演示中文命名映射的各种操作和链式调用
 */

// 支持 CommonJS 和 ES 模块导入
const mapModule = require('../../zh/公共函数/zh-map.js');
const {
  映射
} = mapModule || {
  映射: mapModule.映射 || mapModule.default
};

console.log('=== 映射(Map)模块 (zh-map.js) 使用示例 ===\n');

// ===== 1. 基本映射操作 =====
console.log('1. 基本映射操作:');

// 1.1 创建映射并添加元素
console.log('创建空映射并添加元素:');
const 基本映射 = new 映射()
  .添加('键1', '值1')
  .添加('键2', 2)
  .添加('键3', { 名称: '对象值' });

console.log('  映射大小:', 基本映射.大小());
console.log('  映射条目:', 基本映射.取条目());

// 1.2 检查键是否存在并获取值
console.log('  是否包含键2:', 基本映射.包含('键2'));
console.log('  键2的值:', 基本映射.取('键2'));
console.log('  不存在的键值:', 基本映射.取('不存在的键'));

// 1.3 批量添加条目
const 批量映射 = 基本映射.批量添加([
  ['键4', 4],
  ['键5', [1, 2, 3]],
  ['键6', () => console.log('函数值')]
]);
console.log('\n  批量添加后映射:');
批量映射.遍历((值, 键) => {
  console.log(`    ${键}: ${JSON.stringify(值, (k, v) => 
    typeof v === 'function' ? '[Function]' : v)}`);
});

// ===== 2. 删除操作 =====
console.log('\n2. 删除操作:');

// 2.1 删除单个键
const 删除后映射 = 批量映射.删除('键3');
console.log('  删除键3后的映射键列表:', 删除后映射.取键());

// 2.2 批量删除多个键
const 批量删除后映射 = 删除后映射.批量删除('键4', '键5');
console.log('  批量删除键4和键5后的映射大小:', 批量删除后映射.大小());
console.log('  批量删除后映射键列表:', 批量删除后映射.取键());

// 2.3 清空映射
const 空映射 = 批量删除后映射.清空();
console.log('  清空后的映射大小:', 空映射.大小());

// ===== 3. 创建映射的不同方式 =====
console.log('\n3. 创建映射的不同方式:');

// 3.1 使用静态方法创建
const 静态创建映射 = 映射.创建([
  ['a', 1],
  ['b', 2],
  ['c', 3]
]);
console.log('  静态方法创建的映射:', 静态创建映射.取条目());

// 3.2 从普通对象创建映射
const 源对象 = {
  名称: '测试对象',
  版本: '1.0.0',
  活跃: true
};
const 从对象映射 = 映射.从对象(源对象);
console.log('  从对象创建的映射:');
从对象映射.遍历((值, 键) => {
  console.log(`    ${键}: ${值}`);
});

// 3.3 使用复杂键类型
const 复杂键映射 = new 映射();
const 数组键 = [1, 2];
const 对象键 = { id: 1 };
const 函数键 = () => {};

const 复杂键结果 = 复杂键映射
  .添加(数组键, '数组作为键')
  .添加(对象键, '对象作为键')
  .添加(函数键, '函数作为键');

console.log('\n  复杂键类型示例:');
console.log(`    数组键值: ${复杂键结果.取(数组键)}`);
console.log(`    对象键值: ${复杂键结果.取(对象键)}`);
console.log(`    函数键值: ${复杂键结果.取(函数键)}`);

// ===== 4. 链式调用操作 =====
console.log('\n4. 链式调用操作:');

// 4.1 组合多个操作
const 链式映射 = new 映射()
  .添加('x', 10)
  .添加('y', 20)
  .添加('z', 30)
  .删除('y')
  .添加('w', 40);

console.log('  链式调用后的映射:');
链式映射.遍历((值, 键) => {
  console.log(`    ${键}: ${值}`);
});

// 4.2 映射值操作
const 映射值结果 = 链式映射.映射值((值, 键) => {
  return 值 * 2; // 将所有值乘以2
});

console.log('  映射值(乘2)结果:');
映射值结果.遍历((值, 键) => {
  console.log(`    ${键}: ${值}`);
});

// 4.3 过滤操作
const 过滤结果 = 映射值结果.过滤((值, 键) => {
  return 值 > 25; // 只保留值大于25的条目
});

console.log('  过滤(值>25)结果:');
过滤结果.遍历((值, 键) => {
  console.log(`    ${键}: ${值}`);
});

// ===== 5. 映射合并操作 =====
console.log('\n5. 映射合并操作:');

// 5.1 合并两个映射
const 映射1 = new 映射([['a', 1], ['b', 2]]);
const 映射2 = new 映射([['b', 20], ['c', 3]]);
const 合并结果 = 映射1.合并(映射2);

console.log('  合并前映射1:', 映射1.取条目());
console.log('  合并前映射2:', 映射2.取条目());
console.log('  合并结果:', 合并结果.取条目());

// 5.2 合并多个映射和原生Map
const 原生Map = new Map([['d', 4], ['a', 100]]);
const 多映射合并 = 映射1.合并(映射2, 原生Map);

console.log('  合并原生Map结果:', 多映射合并.取条目());

// ===== 6. 转换和获取操作 =====
console.log('\n6. 转换和获取操作:');

// 6.1 获取键、值和条目数组
const 示例映射 = new 映射([
  ['name', '映射示例'],
  ['age', 2],
  ['active', true]
]);

console.log('  键数组:', 示例映射.取键());
console.log('  值数组:', 示例映射.取值列表());
console.log('  条目数组:', 示例映射.取条目());

// 6.2 转换为数组
const 转数组结果 = 示例映射.转数组();
console.log('  转数组结果:', 转数组结果);

// 6.3 获取原始Map的副本
const 原始Map副本 = 示例映射.取值();
console.log('  原始Map副本类型:', Object.prototype.toString.call(原始Map副本));

// ===== 7. 遍历和克隆操作 =====
console.log('\n7. 遍历和克隆操作:');

// 7.1 使用遍历方法
console.log('  遍历映射:');
示例映射.遍历((值, 键, 原映射) => {
  console.log(`    ${键}: ${值}`);
});

// 7.2 克隆映射并验证
const 克隆映射 = 示例映射.克隆();
const 克隆后修改 = 克隆映射.添加('newKey', 'newValue');

console.log('  克隆后原映射:', 示例映射.取条目());
console.log('  修改后的克隆映射:', 克隆后修改.取条目());

// ===== 8. 判断和辅助方法 =====
console.log('\n8. 判断和辅助方法:');

// 8.1 判断是否为Map实例
const 测试对象 = { a: 1 };
const 测试Map = new Map();

console.log('  测试普通对象是否为Map:', 映射.是否映射(测试对象));
console.log('  测试Map实例是否为Map:', 映射.是否映射(测试Map));

// 8.2 使用打印方法
console.log('  打印映射内容:');
示例映射.打印();

// ===== 9. 实际应用场景 =====
console.log('\n9. 实际应用场景:');

// 9.1 用户数据管理
console.log('\n9.1 用户数据管理:');
const 用户映射 = new 映射();

// 添加用户
const 添加用户 = (id, 用户数据) => {
  return 用户映射.添加(id, 用户数据);
};

// 查找用户
const 查找用户 = (id) => {
  return 用户映射.取(id);
};

// 更新用户信息
const 更新用户 = (id, 更新数据) => {
  const 现有用户 = 用户映射.取(id);
  if (!现有用户) return 用户映射;
  
  return 用户映射.添加(id, {
    ...现有用户,
    ...更新数据,
    更新时间: new Date().toLocaleString()
  });
};

// 删除非活跃用户
const 删除非活跃用户 = () => {
  return 用户映射.过滤((用户, id) => 用户.活跃);
};

// 添加一些用户
let 当前用户映射 = 添加用户('u001', {
  名称: '张三',
  年龄: 28,
  活跃: true,
  创建时间: new Date().toLocaleString()
});

当前用户映射 = 添加用户('u002', {
  名称: '李四',
  年龄: 32,
  活跃: false,
  创建时间: new Date().toLocaleString()
});

当前用户映射 = 添加用户('u003', {
  名称: '王五',
  年龄: 25,
  活跃: true,
  创建时间: new Date().toLocaleString()
});

// 更新用户
当前用户映射 = 更新用户('u001', { 年龄: 29 });

// 显示用户列表
console.log('  所有用户:');
当前用户映射.遍历((用户, id) => {
  console.log(`    ${id}: ${用户.名称}, ${用户.年龄}岁, ${用户.活跃 ? '活跃' : '非活跃'}`);
});

// 删除非活跃用户
const 活跃用户映射 = 删除非活跃用户();
console.log('\n  活跃用户:');
活跃用户映射.遍历((用户, id) => {
  console.log(`    ${id}: ${用户.名称}, ${用户.年龄}岁`);
});

// 9.2 配置管理系统
console.log('\n9.2 配置管理系统:');
const 配置管理器 = {
  配置: new 映射(),
  
  设置(键, 值) {
    this.配置 = this.配置.添加(键, 值);
    return this;
  },
  
  获取(键, 默认值) {
    const 值 = this.配置.取(键);
    return 值 !== undefined ? 值 : 默认值;
  },
  
  批量设置(配置项) {
    this.配置 = this.配置.批量添加(配置项);
    return this;
  },
  
  移除(键) {
    this.配置 = this.配置.删除(键);
    return this;
  },
  
  导出为对象() {
    const 结果 = {};
    this.配置.遍历((值, 键) => {
      结果[键] = 值;
    });
    return 结果;
  },
  
  加载(配置对象) {
    this.配置 = 映射.从对象(配置对象);
    return this;
  }
};

// 设置配置
配置管理器
  .设置('端口', 3000)
  .设置('主机', 'localhost')
  .设置('调试模式', true)
  .批量设置([
    ['最大连接数', 100],
    ['超时时间', 5000]
  ]);

console.log('  配置项:');
配置管理器.配置.遍历((值, 键) => {
  console.log(`    ${键}: ${值}`);
});

console.log('  获取单个配置 - 端口:', 配置管理器.获取('端口'));
console.log('  获取不存在配置 - 数据库:', 配置管理器.获取('数据库', '默认值'));

// 更新配置
配置管理器.移除('调试模式').设置('调试模式', false);
console.log('  更新后调试模式:', 配置管理器.获取('调试模式'));

// 9.3 缓存管理系统
console.log('\n9.3 缓存管理系统:');
const 缓存系统 = {
  缓存: new 映射(),
  
  设置(键, 值, 过期时间毫秒) {
    const 缓存项 = {
      值,
      过期时间: 过期时间毫秒 ? Date.now() + 过期时间毫秒 : null
    };
    this.缓存 = this.缓存.添加(键, 缓存项);
    return this;
  },
  
  获取(键) {
    const 缓存项 = this.缓存.取(键);
    if (!缓存项) return null;
    
    // 检查是否过期
    if (缓存项.过期时间 && Date.now() > 缓存项.过期时间) {
      this.缓存 = this.缓存.删除(键);
      return null;
    }
    
    return 缓存项.值;
  },
  
  清除过期() {
    this.缓存 = this.缓存.过滤((缓存项, 键) => {
      return !缓存项.过期时间 || Date.now() <= 缓存项.过期时间;
    });
    return this;
  },
  
  清除(键) {
    this.缓存 = this.缓存.删除(键);
    return this;
  },
  
  清空() {
    this.缓存 = this.缓存.清空();
    return this;
  },
  
  大小() {
    return this.缓存.大小();
  }
};

// 设置缓存项
缓存系统
  .设置('用户1', { 名称: '张三', 角色: '管理员' })
  .设置('临时数据', '这是临时内容', 2000) // 2秒后过期
  .设置('配置', { 主题: '暗色', 语言: '中文' });

console.log('  缓存大小:', 缓存系统.大小());
console.log('  获取用户1:', JSON.stringify(缓存系统.获取('用户1')));
console.log('  获取临时数据:', 缓存系统.获取('临时数据'));

// 等待临时数据过期
setTimeout(() => {
  console.log('\n  2秒后检查过期缓存:');
  console.log('  临时数据是否存在:', 缓存系统.获取('临时数据') !== null ? '是' : '否');
  console.log('  执行清除过期后缓存大小:', 缓存系统.清除过期().大小());
  
  console.log('\n=== 所有映射示例执行完成 ===');
}, 2100);
